﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using LevenBlog.Core.Entities;
using LevenBlog.Core.Service;
using LevenBlog.Core.WcfService;
using LevenBlog.Core.Utils;

namespace LevenBlog.WcfService {
    // NOTE: If you change the class name "BlogService" here, you must also update the reference to "BlogService" in Web.config.
    public class BlogService : BaseService, IBlogService {
        #region IBlogService Members

        public lb_config GetConfig() {
            return Config;
        }

        public lb_state GetState() {
            return State;
        }

        public List<lb_category> GetCategories() {
            var result = Category.Get(Provider);
            result = result.OrderBy(c => c.order).ToList();
            return result as List<lb_category>;
        }

        public int CountBlog(int? categoryId, BlogState? state) {
            int result = 0;
            if (!categoryId.HasValue) {
                if (state.HasValue) {
                    result = Blog.Count(Provider, state.Value);
                } else {
                    result = Blog.Count(Provider);
                }
            } else {
                if (state.HasValue) {
                    result = Blog.Count(Provider, categoryId.Value, state.Value);
                } else {
                    result = Blog.Count(Provider, categoryId.Value);
                }
            }
            return result;
        }

        public List<lb_blog> GetBlogList(int? categoryId, int page, BlogState state) {
            IList<lb_blog> result;
            if (categoryId == null) {
                result = Blog.Get(Provider, Config.blogpage, page, state);
            } else {
                result = Blog.Get(Provider, categoryId.Value, Config.blogpage, page, state);
            }
            return result as List<lb_blog>;
        }

        public int CountBlogByDateTime(DateTime? startTime, DateTime? endTime, BlogState state) {
            startTime = startTime ?? DateTime.MinValue;
            endTime = endTime ?? DateTime.MinValue;
            return Blog.CountFromDateTime(Provider, startTime.Value, endTime.Value, state);
        }

        public int CountBlogByTag(string tag, BlogState state) {
            return Blog.CountFromSearchTags(Provider, tag, state);
        }

        public int CountBlogByTitle(string s, BlogState state) {
            return Blog.CountFromSearchTitle(Provider, s, state);
        }

        public List<lb_blog> GetBlogListByDateTime(DateTime? startTime, DateTime? endTime, int page, BlogState state) {
            startTime = startTime ?? DateTime.MinValue;
            endTime = endTime ?? DateTime.MinValue;
            var result = Blog.Get(Provider, startTime.Value, endTime.Value, Config.blogpage, page, state);
            return result as List<lb_blog>;
        }

        public List<lb_blog> SearchBlogListByTag(string tag, int page, BlogState state) {
            if (String.IsNullOrEmpty(tag)) {
                throw new FaultException("搜索tag不能为空.");
            }
            var result = Blog.SearchTags(Provider, tag, Config.blogpage, page, state);
            return result as List<lb_blog>;
        }

        public List<lb_blog> SearchBlogListByTitle(string s, int page, BlogState state) {
            if (String.IsNullOrEmpty(s)) {
                throw new FaultException("搜索关键字不能为空.");
            }
            var result = Blog.SearchTitle(Provider, s, Config.blogpage, page, state);
            return result as List<lb_blog>;
        }


        public lb_blog GetBlog(int id) {
            var result = Blog.Get(Provider, id);
            return result;
        }

        public Pair<lb_blog, lb_blog> GetAboutBlog(int id) {
            var result = Blog.GetAbout(Provider, id);
            return result;
        }

        public int[] GetBlogWriteDays(int year, int month) {
            var result = Blog.GetWriteDays(Provider, year, month);
            return result.ToArray();
        }

        public List<lb_blog> GetTopBlogList(int num) {
            if (num <= 0)
                num = 10;
            return Blog.Get(Provider, num, 1, BlogState.Show) as List<lb_blog>;
        }

        public List<lb_comment> GetTopCommentList(int num) {
            if (num <= 0)
                num = 10;
            return Comment.Get(Provider, num, 1, CommentState.Show) as List<lb_comment>;
        }

        public List<lb_archive> GetArchive() {
            return Archive.Get(Provider) as List<lb_archive>;
        }

        public List<lb_friendlink> GetIndexLinkList() {
            return FriendLink.Get(Provider)
                .Where(e => e.isshow == true && e.isindex == true)
                .OrderBy(e => e.order)
                .ToList();
        }

        public List<lb_friendlink> GetLinkList() {
            return FriendLink.Get(Provider) as List<lb_friendlink>;
        }

        public string Login(string username, string password) {
            if (String.IsNullOrEmpty(username) || String.IsNullOrEmpty(password)) {
                throw new FaultException("用户名和密码都不能为空");
            }
            lb_user user = BlogUser.Get(Provider, username);
            if (user != null && user.password.Equals(password.ToMD5(), StringComparison.CurrentCultureIgnoreCase)) {
                lb_user tokenUser = new lb_user() {
                    id = user.id,
                    name = user.name,
                    password = user.password,
                    postnum = user.postnum,
                    typeid = user.typeid
                };
                return base.EncryptUserToken(tokenUser);
            } else {
                return String.Empty;
            }
        }

        public lb_user GetCurrentUser(string token) {
            lb_user result = null;
            if (TryDecryptUserToken(token, out result)) {
                return BlogUser.Get(Provider, result.id);
            } else {
                return null;
            }
        }

        public void AddBlog(string token, lb_blog blog) {
            lb_user user;
            if (!TryDecryptUserToken(token, out user)) {
                throw new FaultException("请先登录系统.");
            }
            var authority = GetAuthority(user);
            if (authority == null || !authority.Post)
                throw new FaultException("您无权进行该操作");
            blog.postuser = user.name;
            Blog.Insert(Provider, blog);
        }

        public void AddComment(string token, lb_comment comment) {
            lb_user user;
            if (!TryDecryptUserToken(token, out user)) {
                throw new FaultException("请先登录系统.");
            }
            var authority = GetAuthority(user);
            if (authority == null || !authority.Comment)
                throw new FaultException("您无权进行该操作");
            comment.userid = user.id;
            Comment.Insert(Provider, comment);
        }

        public void UpdateUser(string token, lb_user user) {
            lb_user tokenUser;
            if (!TryDecryptUserToken(token, out tokenUser)) {
                throw new FaultException("请先登录系统.");
            }
            tokenUser.password = user.password;
            BlogUser.Update(Provider, tokenUser);
        }

        public void UpdateUserInfo(string token, lb_userinfo info) {
            lb_user tokenUser;
            if (!TryDecryptUserToken(token, out tokenUser)) {
                throw new FaultException("请先登录系统.");
            }
            lb_user user = BlogUser.Get(Provider, tokenUser.id);
            info.userid = user.id;
            user.userinfo = info;
            BlogUser.Update(Provider, user);
        }

        public void DeleteBlog(string token, int id) {
            lb_user tokenUser;
            if (!TryDecryptUserToken(token, out tokenUser)) {
                throw new FaultException("请先登录系统.");
            }
            var authority = GetAuthority(tokenUser);
            if (authority == null || !authority.Delete)
                throw new FaultException("您无权进行该操作");
            Blog.Delete(Provider, id);
        }

        public void DeleteComment(string token, int id) {
            lb_user tokenUser;
            if (!TryDecryptUserToken(token, out tokenUser)) {
                throw new FaultException("请先登录系统.");
            }
            var authority = GetAuthority(tokenUser);
            if (authority == null || !authority.Delete)
                throw new FaultException("您无权进行该操作");
            Comment.Delete(Provider, id);
        }

        #endregion
    }
}
